package com.dbex.core;

import java.sql.ResultSet;
import java.util.List;

import com.dbex.util.ArrayUtils;
import com.dbex.util.DBUtil;
import com.dbex.util.MainConfig;
import com.dbex.util.RowMapper;

public class OracleDialect implements Dialect {
	
	private static final String FIND_ALL_TABLES = "select a1.TABLE_NAME from all_tables a1 where a1.OWNER = ?";
	
	/**
	 * 查询某个表下所有的列：列名，数据类型，数据长度（字节），数字精度，小数位数，字符长度（char），char类型（B--byte,C--char）
	 */
	private static final String FIND_COLS_OF_TABLE = "select atc.COLUMN_NAME,atc.DATA_TYPE,atc.DATA_LENGTH,atc.DATA_PRECISION,atc.DATA_SCALE,atc.CHAR_LENGTH,atc.CHAR_USED from all_tab_cols atc where atc.OWNER = ? and atc.TABLE_NAME = ?";
	
	private static final String DATE_FORMAT = "yyyy-mm-dd hh24:mi:ss";

	@SuppressWarnings({ "rawtypes" })
	@Override
	public Table[] getAllTables() {
		String srcSchema = MainConfig.getValue("src.schema");
		srcSchema = srcSchema.toUpperCase();
		List list= DBUtil.queryList(FIND_ALL_TABLES,srcSchema);
		Table[] tables = new Table[list.size()];
		for (int i = 0; i < list.size(); i++) {
			String tableName = list.get(i).toString();
			Column[] columns= DBUtil.queryList(FIND_COLS_OF_TABLE, new RowMapper<Column>(){

				@Override
				public Column rowMapper(ResultSet rs) throws Exception {
					Column column = new Column();
					column.setColumnName(rs.getString(1));
					String type = rs.getString(2);
					if("NUMBER".equals(type)){
						column.setColumnType("number");
						column.setPrecision(rs.getInt(4));
						column.setScale(rs.getInt(5));
					}else if (ArrayUtils.contains(new String[]{"VARCHAR","VARCHAR2"}, type)) {
						column.setColumnType("string");
						column.setVar(true);
					}else if ("CHAR".equals(type)) {
						column.setColumnType("string");
						column.setVar(false);
					}else if ("DATE".equals(type)) {
						column.setColumnType("date");
					}else{
						throw new RuntimeException("不识别的类型:"+type);
					}
					column.setLength(rs.getInt(3));
					return column;
				}
				
			}, srcSchema, tableName).toArray(new Column[0]);
			tables[i] = new Table(srcSchema,tableName,columns);
		}
		return tables;
	}

	@Override
	public String toChar(String columnName) {
		return "to_char("+columnName+",'"+DATE_FORMAT+"')";
	}

	@Override
	public String toDate(String columnValue) {
		return "to_date('"+columnValue+"','"+DATE_FORMAT+"')";
	}

	@Override
	public boolean isString(String columnType) {
		return ArrayUtils.contains(new String[]{"VARCHAR","VARCHAR2","CHAR"}, columnType);
	}

	@Override
	public boolean isNumber(String columnType) {
		return ArrayUtils.contains(new String[]{"NUMBER","LONG","FLOAT","DECIMAL","DOUBLE"}, columnType);
	}

	@Override
	public boolean isDate(String columnType) {
		return ArrayUtils.contains(new String[]{"DATE","DATETIME"}, columnType);
	}

	@Override
	public String geneColumnType(Column column) {
//		String dataType = column[1].toString();
//		String columnType = dataType;
//		if("NUMBER".equals(dataType)){
//			if(column[3]!=null){
//				columnType+='('+column[3].toString();
//				if(column[4]!=null){
//					columnType += ','+column[4].toString();
//				}
//				columnType += ')';
//			}
//		}else if (isString(dataType)) {
//			String type = column[6].toString();
//			columnType += '('+column[5].toString()+' '+("B".equals(type)?"BYTE":"CHAR")+')';
//		}else if ("FLOAT".equals(dataType)) {
//			columnType += '('+column[3].toString()+')';
//		}
//		return columnType;
		return null;
	}

	@Override
	public String getNumberType(Integer pricision, Integer scale) {
		return "NUMBER("+pricision+","+scale+")";
	}

	@Override
	public String getStringType(boolean isVar, Integer length) {
		String type = "CHAR";
		if(isVar){
			type = "VARCHAR2";
		}
		if(length!=null){
			type += "("+length+" CHAR)";
		}
		return type;
	}


}
